package com.youdianstar.app.ui

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.View
import android.widget.ImageView
import android.widget.Toast
import com.gyf.immersionbar.ImmersionBar
import com.youdianstar.app.BR
import com.youdianstar.app.R
import com.youdianstar.app.common.Extra
import com.youdianstar.app.common.auko.startActivity
import com.youdianstar.app.common.base.BaseActivity
import com.youdianstar.app.common.event.NetStateLiveData
import com.youdianstar.app.common.network.LocalCookieJar
import com.youdianstar.app.common.network.SerializableCookie
import com.youdianstar.app.common.network.model.BaseResponse
import com.youdianstar.app.common.util.CacheUtil
import com.youdianstar.app.common.util.LogUtil
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.youdianstar.app.common.util.MathUtil
import com.youdianstar.app.common.util.StrUtil
import com.youdianstar.app.databinding.ActivityDepositPaymentBinding
import com.youdianstar.app.entity.SecurityPayConfigResponse
import com.youdianstar.app.support.ApiRepository
import com.youdianstar.app.util.DataAppManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.HttpUrl
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import android.util.Base64

class DepositPaymentActivity : BaseActivity<ActivityDepositPaymentBinding, ScanViewModel>(), KoinComponent {

    private val apiRepository: ApiRepository by inject()

    override fun layoutId(): Int = R.layout.activity_deposit_payment

    override fun initVariableId(): Int = BR.viewModel

    override fun initViewModel(): ScanViewModel {
        val model: ScanViewModel by viewModel()
        return model
    }

    private var deviceId: String = ""
    private var powerBankType: Int = 0
    private var securityFee: Double = 0.0 // 将从接口获取真实值
    private var selectedPaymentMethod: String = "zalopay" // zalopay or momo
    
    // 押金配置接口响应
    private val configLiveData = NetStateLiveData<SecurityPayConfigResponse>()
    
    // 定时器
    private var loadingTimeoutHandler: Handler? = null
    private var loadingTimeoutRunnable: Runnable? = null
    private var closePageHandler: Handler? = null
    private var closePageRunnable: Runnable? = null
    
    companion object {
        private const val LOADING_TIMEOUT_MS = 10_000L // 10秒后自动取消loading
        private const val CLOSE_PAGE_TIMEOUT_MS = 60_000L // 1分钟后自动关闭页面
        private const val BASE_URL = "https://s.youdianstar.com"
    }

    override fun initData() {
        super.initData()
        ImmersionBar.with(this).statusBarDarkFont(true).init()
        
        // 获取传递的参数
        deviceId = intent.getStringExtra(Extra.IT_MSG) ?: ""
        powerBankType = intent.getIntExtra("powerBankType", 0)
        // 如果Intent中有传递押金金额，先使用（接口返回后会覆盖）
        securityFee = intent.getDoubleExtra("securityFee", 0.0)
        
        if (StrUtil.isEmpty(deviceId)) {
            finish()
            return
        }

        // 调用接口获取真实的押金金额
        loadSecurityFeeConfig()
        
        // 设置支付方式选中状态
        updatePaymentMethodUI()
    }
    
    /**
     * 加载押金配置（获取真实押金金额）
     */
    private fun loadSecurityFeeConfig() {
        showLoadingDialog()
        CoroutineScope(Dispatchers.IO).launch {
            apiRepository.getSecurityPayConfig(powerBankType, configLiveData)
        }
    }

    override fun initClickEvent() {
        // ZaloPay选项
        findViewById<View>(R.id.cl_zalo_pay).setOnClickListener {
            selectedPaymentMethod = "zalopay"
            updatePaymentMethodUI()
        }
        
        // MoMo选项
        findViewById<View>(R.id.cl_momo).setOnClickListener {
            selectedPaymentMethod = "momo"
            updatePaymentMethodUI()
        }
        
        // 立即支付按钮
        mBinding.btnPayNow.setOnClickListener {
            handlePayment()
        }
    }

    override fun initLiveObserver() {
        super.initLiveObserver()
        
        // 监听押金配置接口返回
        configLiveData.observe(this) { response: BaseResponse<SecurityPayConfigResponse> ->
            LogUtil.d("DepositPaymentActivity", "收到接口响应: code=${response.code}, dataState=${response.dataState}, data=${response.data}")
            
            // 无论响应码是什么，只要有数据就处理
            response.data?.let { config: SecurityPayConfigResponse ->
                try {
                    // 使用接口返回的真实押金金额
                    securityFee = config.rentboxRuleConfig.securityFee
                    
                    // 更新UI显示
                    updateDepositAmountUI()
                    dismissDialog()
                } catch (e: Exception) {
                    e.printStackTrace()
                    updateDepositAmountUI()
                    dismissDialog()
                }
            } ?: run {
                // 数据为空
                LogUtil.w("DepositPaymentActivity", "接口返回数据为空: code=${response.code}, dataState=${response.dataState}, message=${response.message}")
                
                // 即使数据为空，也要关闭加载对话框
                updateDepositAmountUI()
                dismissDialog()
            }
        }
    }
    
    /**
     * 更新押金金额UI显示
     */
    private fun updateDepositAmountUI() {
        // 只有当押金金额大于0时才显示
        if (securityFee > 0) {
            // 使用formatVietnameseDong格式化金额，每3位加一个点
            val formattedAmount = MathUtil.formatVietnameseDong(securityFee)
            mBinding.tvDepositAmount.text = formattedAmount
        } else {
            mBinding.tvDepositAmount.text = ""
        }
    }

    private fun updatePaymentMethodUI() {
        // 更新ZaloPay选中状态
        val zalopayView = findViewById<View>(R.id.cl_zalo_pay)
        val zalopayRadio = findViewById<android.widget.ImageView>(R.id.iv_zalo_pay_radio)
        if (selectedPaymentMethod == "zalopay") {
            zalopayView.setBackgroundResource(R.color.light_orange_background)
            zalopayRadio.setImageResource(R.drawable.radio_selected)
        } else {
            zalopayView.setBackgroundResource(android.R.color.transparent)
            zalopayRadio.setImageResource(R.drawable.radio_unselected)
        }
        
        // 更新MoMo选中状态
        val momoView = findViewById<View>(R.id.cl_momo)
        val momoRadio = findViewById<android.widget.ImageView>(R.id.iv_momo_radio)
        if (selectedPaymentMethod == "momo") {
            momoView.setBackgroundResource(R.color.light_orange_background)
            momoRadio.setImageResource(R.drawable.radio_selected)
        } else {
            momoView.setBackgroundResource(android.R.color.transparent)
            momoRadio.setImageResource(R.drawable.radio_unselected)
        }
    }

    private fun handlePayment() {
        // 显示全屏loading
        showLoadingDialog(getString(R.string.deposit_payment_processing))
        
        // 置灰按钮
        mBinding.btnPayNow.isEnabled = false
        mBinding.btnPayNow.alpha = 0.5f
        
        // 启动定时器，10秒后自动取消loading（但保持按钮置灰）
        startLoadingTimer()
        
        // 启动关闭页面定时器，1分钟后自动关闭页面
        startClosePageTimer()
        
        // 直接打开浏览器访问H5支付页面
        launchPayment()
    }
    
    /**
     * 启动支付（直接打开浏览器访问H5支付页面）
     */
    private fun launchPayment() {
        // 构建H5支付页面URL
        // 格式：https://s.youdianstar.com/sw/app/callback_APP.html?type=android&deviceId=deviceId&payType=zalo或momo
        val baseUrl = BASE_URL
        
        // 根据选择的支付方式确定payType值
        val payType = when (selectedPaymentMethod) {
            "momo" -> "momo"
            "zalopay" -> "zalo"
            else -> "zalo"
        }
        
        // 获取当前时间戳（秒）
        val timestamp = System.currentTimeMillis() / 1000
        
        // 构建基础URL（显示在地址栏的参数），添加时间戳避免重复跳转到同一个URL
        val h5Url = "$baseUrl/sw/app/callback_APP.html?type=android&deviceId=$deviceId&payType=$payType&_t=$timestamp"
        
        // 将登录cookie等信息通过hash（#）传递，这样不会显示在地址栏，H5可以通过JavaScript读取
        // 使用Base64编码，避免明文显示
        val hashParams = StringBuilder("#")
        
        // 获取cookie信息（参考iOS：从cookie存储中获取所有相关cookie）
        val cookieString = getCookieString()
        if (cookieString.isNotEmpty()) {
            try {
                // 将cookie字符串进行Base64编码
                val encodedCookies = Base64.encodeToString(cookieString.toByteArray(Charsets.UTF_8), Base64.NO_WRAP)
                // Base64编码可能包含+、/、=等特殊字符，需要进行URL编码
                val urlEncodedCookies = Uri.encode(encodedCookies)
                hashParams.append("cookies=$urlEncodedCookies")
                LogUtil.d("DepositPaymentActivity", "Cookie信息 - 原始长度: ${cookieString.length}, Base64编码后长度: ${encodedCookies.length}")
            } catch (e: Exception) {
                LogUtil.e("DepositPaymentActivity", "编码cookie失败: ${e.message}")
            }
        }
        
        // 添加platform-id（如果有）
        val userInfo = DataAppManager.instance.getUser()
        val platformId = userInfo?.platformId
        if (platformId != null && platformId > 0) {
            if (hashParams.length > 1) {
                hashParams.append("&")
            }
            hashParams.append("platformId=$platformId")
        }
        
        if (hashParams.length <= 1) {
            LogUtil.w("DepositPaymentActivity", "没有找到任何cookie或token信息")
        }
        
        val finalUrl = h5Url + if (hashParams.length > 1) hashParams.toString() else ""
        
        // 打印完整的跳转URL链接
        LogUtil.d("DepositPaymentActivity", "═══════════════════════════════════════")
        LogUtil.d("DepositPaymentActivity", "📍 [支付跳转] 完整URL链接:")
        LogUtil.d("DepositPaymentActivity", finalUrl)
        LogUtil.d("DepositPaymentActivity", "═══════════════════════════════════════")
        LogUtil.d("DepositPaymentActivity", "准备打开H5支付页面: $h5Url")
        LogUtil.d("DepositPaymentActivity", "Hash参数（不显示在地址栏）: ${if (hashParams.length > 1) hashParams.toString() else "无"}")
        
        try {
            val uri = Uri.parse(finalUrl)
            if (uri != null) {
                // 直接打开系统浏览器打开支付URL
                val intent = Intent(Intent.ACTION_VIEW, uri)
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                if (intent.resolveActivity(packageManager) != null) {
                    startActivity(intent)
                    LogUtil.d("DepositPaymentActivity", "✅ 已打开系统浏览器，H5支付页面")
                    // 保持loading和按钮置灰，等待H5支付回调
                } else {
                    // 失败时取消定时器、恢复按钮状态并隐藏loading
                    cancelLoadingTimer()
                    cancelClosePageTimer()
                    dismissDialog()
                    mBinding.btnPayNow.isEnabled = true
                    mBinding.btnPayNow.alpha = 1.0f
                    LogUtil.e("DepositPaymentActivity", "无法打开浏览器")
                    Toast.makeText(this, getString(R.string.deposit_payment_start_failed, "无法打开浏览器"), Toast.LENGTH_SHORT).show()
                }
            } else {
                // URL格式错误
                cancelLoadingTimer()
                cancelClosePageTimer()
                dismissDialog()
                mBinding.btnPayNow.isEnabled = true
                mBinding.btnPayNow.alpha = 1.0f
                LogUtil.e("DepositPaymentActivity", "支付URL格式错误: $finalUrl")
                Toast.makeText(this, getString(R.string.deposit_payment_start_failed, "URL格式错误"), Toast.LENGTH_SHORT).show()
            }
        } catch (e: Exception) {
            // 失败时取消定时器、恢复按钮状态并隐藏loading
            cancelLoadingTimer()
            cancelClosePageTimer()
            dismissDialog()
            mBinding.btnPayNow.isEnabled = true
            mBinding.btnPayNow.alpha = 1.0f
            LogUtil.e("DepositPaymentActivity", "打开浏览器失败: ${e.message}")
            Toast.makeText(this, getString(R.string.deposit_payment_start_failed, e.message ?: ""), Toast.LENGTH_SHORT).show()
        }
    }
    
    /**
     * 获取cookie字符串（参考iOS：从cookie存储中获取所有相关cookie）
     */
    private fun getCookieString(): String {
        try {
            // 直接从缓存中读取所有cookie（参考iOS的NSHTTPCookieStorage方式）
            val cookieJson = CacheUtil.instance.getStringValue("cookies", "")
            if (cookieJson.isEmpty()) {
                LogUtil.d("DepositPaymentActivity", "缓存中没有cookie数据")
                return ""
            }
            
            val gson = Gson()
            val type = object : TypeToken<Map<String, List<SerializableCookie>>>() {}.type
            val savedCookies: Map<String, List<SerializableCookie>> = gson.fromJson(cookieJson, type)
            
            LogUtil.d("DepositPaymentActivity", "从缓存中读取到 ${savedCookies.size} 个域名的cookie")
            
            // 查找与当前域名相关的cookie（参考iOS的过滤逻辑）
            val relevantCookies = mutableListOf<okhttp3.Cookie>()
            savedCookies.forEach { (domain, serializableCookies) ->
                // 检查domain是否匹配（localhost或相关域名）
                if (domain.contains("localhost") || 
                    domain.contains("youdian") || 
                    domain.contains("youdianstar")) {
                    
                    serializableCookies.forEach { serializableCookie ->
                        try {
                            val cookie = SerializableCookie.toCookie(serializableCookie)
                            // 检查cookie是否过期
                            if (cookie.expiresAt >= System.currentTimeMillis()) {
                                relevantCookies.add(cookie)
                                LogUtil.d("DepositPaymentActivity", "找到相关Cookie: ${cookie.name} = ${if (cookie.value.length > 50) cookie.value.take(50) + "..." else cookie.value} (domain: ${cookie.domain}, path: ${cookie.path})")
                            }
                        } catch (e: Exception) {
                            LogUtil.e("DepositPaymentActivity", "转换cookie失败: ${e.message}")
                        }
                    }
                }
            }
            
            if (relevantCookies.isNotEmpty()) {
                // 构建cookie字符串（格式：name1=value1;name2=value2）
                val cookieString = relevantCookies.joinToString(";") { cookie ->
                    "${cookie.name}=${cookie.value}"
                }
                LogUtil.d("DepositPaymentActivity", "构建的cookie字符串长度: ${cookieString.length}")
                return cookieString
            } else {
                LogUtil.w("DepositPaymentActivity", "没有找到相关的有效cookie")
            }
        } catch (e: Exception) {
            LogUtil.e("DepositPaymentActivity", "获取cookie失败: ${e.message}")
            e.printStackTrace()
        }
        return ""
    }
    
    /**
     * 启动loading定时器（10秒后自动取消loading，但保持按钮置灰）
     */
    private fun startLoadingTimer() {
        // 先取消之前的定时器（如果存在）
        cancelLoadingTimer()
        
        // 创建定时器，10秒后触发
        loadingTimeoutHandler = Handler(Looper.getMainLooper())
        loadingTimeoutRunnable = Runnable {
            LogUtil.d("DepositPaymentActivity", "⏰ [定时器] 10秒超时，自动取消loading（保持按钮置灰）")
            // 只隐藏loading，不恢复按钮状态
            dismissDialog()
            // 按钮保持置灰状态，不恢复
        }
        
        loadingTimeoutHandler?.postDelayed(loadingTimeoutRunnable!!, LOADING_TIMEOUT_MS)
        LogUtil.d("DepositPaymentActivity", "⏰ [定时器] 已启动loading定时器，10秒后自动取消loading")
    }
    
    /**
     * 取消loading定时器
     */
    private fun cancelLoadingTimer() {
        loadingTimeoutRunnable?.let {
            loadingTimeoutHandler?.removeCallbacks(it)
            loadingTimeoutRunnable = null
        }
        loadingTimeoutHandler = null
    }
    
    /**
     * 启动关闭页面定时器（1分钟后自动关闭页面）
     */
    private fun startClosePageTimer() {
        // 先取消之前的定时器（如果存在）
        cancelClosePageTimer()
        
        // 创建定时器，1分钟（60秒）后触发
        closePageHandler = Handler(Looper.getMainLooper())
        closePageRunnable = Runnable {
            LogUtil.d("DepositPaymentActivity", "⏰ [定时器] 1分钟超时，自动关闭创建订单页面")
            // 在主线程关闭页面
            runOnUiThread {
                finish()
            }
        }
        
        closePageHandler?.postDelayed(closePageRunnable!!, CLOSE_PAGE_TIMEOUT_MS)
        LogUtil.d("DepositPaymentActivity", "⏰ [定时器] 已启动关闭页面定时器，1分钟后自动关闭")
    }
    
    /**
     * 取消关闭页面定时器
     */
    private fun cancelClosePageTimer() {
        closePageRunnable?.let {
            closePageHandler?.removeCallbacks(it)
            closePageRunnable = null
        }
        closePageHandler = null
    }
    
    override fun onDestroy() {
        super.onDestroy()
        // Activity销毁时取消定时器
        cancelLoadingTimer()
        cancelClosePageTimer()
    }
}
